home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-04 | 26.3 KB | 882 lines | [TEXT/PJMM] |
- {This document is formated in monaco 9 pt }
- { }
- {LEGAL STUFF }
- { }
- {Copyright © 1994 by University of Melbourne. All Rights Reserved. This work is }
- {provided "as is" and without any express or implied warranties, including, }
- {without limitation, the implied warranties of merchantability and fitness }
- {for a particular purpose. }
- { }
- {University of Melbourne is not responsible for the consequences of the use of this}
- {work, regardless of the cause. You may use this work in a public domain, }
- {freeware, or shareware product with no restrictions, as long as you include }
- {the following notice in your product's about box or splash screen: }
- { "Portions Copyright © 1994 by University of Melbourne". }
- {If you use more than 50 lines of this work, please credit the author also: }
- { "Portions by Michael Cutter" }
- {Public domain is defined as something that you release to the public, without }
- {copyright and without restrictions on use. Freeware is a copyrighted work, }
- {for which you charge no money. Shareware is a copyrighted work for which you }
- {charge a fee if the user decides to keep it. If you intend to use this work }
- {in a commercial product, please contact us. }
- { }
- { }
- {OTHER STUFF }
- { }
- {AUTHOR: }
- { Michael Trevor Cutter }
- { }
- {CONTACT: }
- { Internet: }
- { mtc@arbld.unimelb.edu.au (Preferred) }
- { Snail Mail: }
- { Dept of Architecture & Building }
- { University of Melbourne }
- { Parkville VIC 3052 }
- { AUSTRALIA }
- { }
- {PERSONAL STUFF }
- { I'd really appreciate it if you'd let me know what you're using my code }
- { in, (send me email or a postcard). Please report any bugs or errors to me. }
- { }
- {MODULE DESCRIPTION }
- {This unit provides functions for obtaining various information about files and }
- {folders. The functions were created on an 'as needed' basis, so there isn't much }
- {rhyme or reason to them. They are just my best go at doing what I needed to do. }
- {Please feel free to make suggestions about how they might be improved, I always }
- {enjoy constructive criticism :-) }
-
- unit MCFileInfo;
- interface
- uses
- Folders,{}
- MCCompatibility, MCCursor, MCHandlesAndStrs;
- function GestaltAvailable: boolean;
- function GestHasFSSpecCalls: boolean;
-
- {returns true if the FSSpec _file_ exists}
- function MCFSSpecExists (myFSSpec: FSSpec): boolean;
-
- {get a directory string path from a dirid and vrefnum}
- function MCPathNameFromDirID (DirID: longint;
- vRefnum: integer): string;
-
- {get the type and creator of a file}
- function MCGetTypeCrtr (myfs: FSSpec;
- var ftype, crtr: OSType): OSErr;
- function MCGetType (myfs: FSSpec;
- var ftype: OSType): OSErr;
- function MCGetCrtr (myfs: FSSpec;
- var crtr: OSType): OSErr;
-
- {get and set the namelocked bit of a file}
- function MCLockName (myfs: FSSpec): OSErr;
- function MCUnlockName (myfs: FSSpec): OSErr;
- function MCGetNameLock (myfs: FSSpec;
- var namelock: Boolean): OSErr;
-
- {list the contents of a directory in a displayable form - not very good}
- {and a bit buggy}
- function MCListDirectory (vrefnum: integer;
- dirid: Longint;
- longlist: boolean;
- listall: boolean;
- markdirs: boolean): Handle;
-
- {much more efficient method of searching a directory}
- {Gives a return delimited list of all the files/folders in the given}
- {directory. Easily modified to do a recursive search of all subfolders}
- function MCSearchCatalog (MinimumItems: integer;
- vrefnumtosearch: integer;
- DirIDToSearch: Longint;
- findfolders: boolean;
- findfiles: boolean;
- ignorenoaccessfolders: boolean): Handle;
-
- {returns the vrefnum and dirid of the current Blessed system folder}
- function MCFindSystemFolder (var foundVRefNum: integer;
- var foundDirID: longint): OSErr;
-
- {gets the vrefnum of the named volume}
- function MCGetVrefNum (volname: str255;
- var vrefnum: integer): OSErr;
-
- {returns true if the error given is because a file is busy}
- function MCIsBusyError (err: OSErr): boolean;
-
- {returns true if the given FSSpec points to a folder}
- function MCFSSpecIsFolder (myfs: FSSpec): boolean;
-
- {returns true if the given FSSpec file is busy}
- function MCFSSpecIsBusy (myfs: FSSpec): boolean;
-
- {gets the name of a volume given its vrefnum}
- function MCGetVolName (vrefnum: integer;
- var volname: str255): OSErr;
-
- {gets the last item in a string path, i.e.the file name }
- function MCGetLeafOfPath (path: str255): str255;
-
- {returns true if a user can _READ_ the files in a dir (remember to check myAccess before }
- {trying to write to it)}
- { FOR SOME STUPID REASON< I HAVE TO PASS IN A COMPLETE PATH TO GET THIS TO WORK!!!!}
- {ANYONE KNOW WHAT I'M DOING WRONG?}
- {myAccess comes back as 'wrs' if total r/w able, and '-' in place of any that are not there}
- {e.g. '-rs' - Similar to Unix permissions}
- function MCUserCanAccessDir (volname: Str255;
- vrefnum: integer;
- dirID: longint;
- var myAccess: str255;
- var myErr: OSErr): boolean;
-
- {returns the directory id of the directory specified in myFS}
- function MCGetDirIDofDir (myFS: FSSpec;
- isvolume: Boolean;
- var dirid: longint): OSErr;
- implementation
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns true if _Gestalt trap is available. Remember that it may not work, }
- {tho - it may not recognise attributes ••}
- function GestaltAvailable: boolean;
- const
- _Gestalt = $A1AD;
- begin
- GestaltAvailable := TrapAvailable(_Gestalt);
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns true if the current system supports FSSpec calls ••}
- function GestHasFSSpecCalls: boolean;
- {This function is called by all the below functions that use FSSpec calls, to }
- {see whether they are available. If FSSpec calls are not, the function either }
- {aborts if necessary, or uses the System 6 compatible methods.}
- var
- myFeature: longint;
- myErr: OSErr;
- myBit: integer;
- begin
- if GestaltAvailable then
- myErr := Gestalt(gestaltFSAttr, myFeature)
- else
- GestHasFSSpecCalls := false;
- if myerr <> noErr then
- GestHasFSSpecCalls := false
- else
- begin
- myBit := gestaltHasFSSpecCalls;
- if BitTst(@myFeature, 31 - myBit) then
- GestHasFSSpecCalls := true
- else
- GestHasFSSpecCalls := false;
- end;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns true if the file but not folder exists. Should expand to cope with folders. ••}
- function MCFSSpecExists (myFSSpec: FSSpec): boolean;
- var
- myErr: OSErr;
- tmpstr: str255;
- fsrefnum: integer;
- begin
- {system 7 compatible, fails if system 6 - probably a bit naughty trying to open the file, but its a quick and sure way...}
- if GestHasFSSpecCalls then
- begin
- myerr := FSpOpenDF(myFSSpec, fsRdPerm, fsrefnum);
- if (myerr = -43) or (myerr = -35) or (myerr = -120) then
- MCFSSpecExists := false
- else
- begin
- myerr := FSClose(fsrefnum);
- MCFSSpecExists := true; {even if myerr <> noErr, must still exist}
- end;
- end
- else
- MCFSSpecExists := false; {not system 7 - what else can I do?}
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• finds a pathname from a dirid and vrefnum ••}
- {system 6 & 7 compatible}
- function MCPathNameFromDirID;
- var
- Block: CInfoPBRec;
- directoryName, FullPathName: str255;
- err: oserr;
-
- begin
- FullPathName := '';
- with block do
- begin
- ioNamePtr := @directoryName;
- ioDrParID := DirId;
- end;
-
- repeat
-
- with block do
- begin
- ioVRefNum := vRefNum;
- ioFDirIndex := -1;
- ioDrDirID := block.ioDrParID;
- end;
- err := PBGetCatInfo(@Block, FALSE);
- if err <> noerr then
- begin
- MCPathNameFromDirID := 'An error has occured.';
- exit(MCPathNameFromDirID);
- end;
- directoryName := concat(directoryName, ':');
- fullPathName := concat(directoryName, fullPathName);
- until block.ioDrDirID = 2;
-
- MCPathNameFromDirID := fullPathName;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- function MCGetTypeCrtr (myfs: FSSpec;
- var ftype, crtr: OSType): OSErr;
- var
- myFinfo: FInfo;
- myErr: OSErr;
- begin
- myErr := FSpGetFInfo(myfs, myFinfo);
- MCGetTypeCrtr := myErr;
- if myErr = noErr then
- begin
- crtr := myFInfo.fdCreator;
- ftype := myFInfo.fdType;
- end;
- end;
-
- function MCGetType (myfs: FSSpec;
- var ftype: OSType): OSErr;
- var
- myFinfo: FInfo;
- myErr: OSErr;
- begin
- myErr := FSpGetFInfo(myfs, myFinfo);
- MCGetType := myErr;
- if myErr = noErr then
- ftype := myFInfo.fdType;
- end;
-
- function MCGetCrtr (myfs: FSSpec;
- var crtr: OSType): OSErr;
- var
- myFinfo: FInfo;
- myErr: OSErr;
- begin
- myErr := FSpGetFInfo(myfs, myFinfo);
- MCGetCrtr := myErr;
- if myErr = noErr then
- crtr := myFInfo.fdCreator;
- end;
-
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• name lock functions ••}
- const
- kNameLockedBit = 12;
- function MCLockName (myfs: FSSpec): OSErr;
- var
- myfinfo: FInfo;
- flg: longint;
- procedure COSErr (err: OSErr);
- begin
- if err <> noErr then
- begin
- MCLockName := err;
- exit(MCLockName);
- end;
- end;
- begin
- MCLockName := noErr;
- COSErr(FSpGetFInfo(myfs, myfinfo));
- flg := myfinfo.fdFlags;
- BSet(flg, kNameLockedBit);
- myfinfo.fdFlags := flg;
- COSErr(FSpSetFInfo(myfs, myfinfo));
- end;
-
- function MCUnlockName (myfs: FSSpec): OSErr;
- var
- myfinfo: FInfo;
- flg: longint;
- procedure COSErr (err: OSErr);
- begin
- if err <> noErr then
- begin
- MCUnlockName := err;
- exit(MCUnlockName);
- end;
- end;
- begin
- MCUnlockName := noErr;
- COSErr(FSpGetFInfo(myfs, myfinfo));
- flg := myfinfo.fdFlags;
- BClr(flg, kNameLockedBit);
- myfinfo.fdFlags := flg;
- COSErr(FSpSetFInfo(myfs, myfinfo));
- end;
-
- function MCGetNameLock (myfs: FSSpec;
- var namelock: Boolean): OSErr;
- var
- myfinfo: FInfo;
- procedure COSErr (err: OSErr);
- begin
- if err <> noErr then
- begin
- MCGetNameLock := err;
- exit(MCGetNameLock);
- end;
- end;
- begin
- MCGetNameLock := noErr;
- COSErr(FSpGetFInfo(myfs, myfinfo));
- namelock := BTst(myfinfo.fdFlags, kNameLockedBit);
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• Directory listing function ••}
- function MCListDirectory (vrefnum: integer;
- dirid: Longint;
- longlist: boolean;
- listall: boolean;
- markdirs: boolean): Handle;
- var
- FName: Str255;
- myCPB: CInfoPBRec;
- err: OSErr;
- TotalFiles, TotalDirectories: integer;
- htext: Handle;
- retpos: integer;
- returnstr, colonstr: str255;
-
- procedure EnumerateCatalog (dirIDToSearch: longint);
- var
- index, i, tmpint: integer;
- indent: str255;
- begin {EnumerateCatalog}
- index := 1;
- repeat
- MCNextAnimCursor;
- {set up the search}
- FName := '';
- myCPB.ioFDirIndex := index;
- myCPB.ioDrDirID := dirIDToSearch;
-
- err := PBGetCatInfo(@myCPB, FALSE); {actually get the information}
-
- if err = noErr then
- if BitTst(@myCPB.ioFlAttrib, 3) then
-
- begin {we have a directory}
- TotalDirectories := TotalDirectories + 1;
- hlock(htext);
- if not listall and (bitand(myCPB.ioDrUsrWds.frFlags, fInvisible) <> 0) then
- {if it is invisible and not list all}
- begin {don't list it}
- end
- else
- begin {list a folder}
- if myCPB.ioNamePtr^ <> '' then
- begin
- {strip any tailing returns, like the one after Icon...}
- retpos := pos(returnstr, myCPB.ioNamePtr^);
- if retpos > 0 then
- delete(myCPB.ioNamePtr^, retpos, 1);
- err := MCAppendStrToHndl(myCPB.ioNamePtr^, htext);
- {if listall, then list them all, bimbo}
- if markdirs then
- err := MCAppendStrToHndl(colonstr, htext);
- if longlist then
- begin
- indent := '';
- tmpint := 35 - length(myCPB.ioNamePtr^);
- for i := 1 to tmpint do
- indent := concat(indent, ' ');
- err := MCAppendStrToHndl(concat(indent, 'Folder'), htext);
- end;
-
- err := MCAppendReturnToHndl(htext);
- end;
- end;
- hunlock(htext);
- err := 0; {clear error return on way back}
- end {if BitTst}
- else
-
- begin {we have a file}
- TotalFiles := TotalFiles + 1;
- hlock(htext);
- if not listall and (bitand(myCPB.ioFLFndrInfo.fdFlags, fInvisible) <> 0) then {if it is invisible and not list all}
- begin {don't list it}
- end
- else
- begin {list a file}
- if myCPB.ioNamePtr^ <> '' then
- begin
- {strip any tailing returns, like the one after Icon...}
- retpos := pos(returnstr, myCPB.ioNamePtr^);
- if retpos > 0 then
- delete(myCPB.ioNamePtr^, retpos, 1);
- err := MCAppendStrToHndl(myCPB.ioNamePtr^, htext);
-
- if longlist then
- begin
- indent := '';
- tmpint := 35 - length(myCPB.ioNamePtr^);
- for i := 1 to tmpint do
- indent := concat(indent, ' ');
- err := MCAppendStrToHndl(concat(indent, myCPB.ioflFndrInfo.fdType, ' ', myCPB.ioflFndrInfo.fdCreator), htext);
- end;
-
- err := MCAppendReturnToHndl(htext);
- end;
- end;
- hunlock(htext);
- {EnumerateCatalog(myCPB.ioDrDirID); {only call this if we want a recursive search}
- err := 0; {clear error return on way back}
- end; {else}
- index := index + 1;
- until (err <> noErr);
- end; {EnumerateCatalog}
-
-
- begin {EnumerShell}
- TotalFiles := 0;
- TotalDirectories := 0;
-
- FName := '';
-
- with MyCPB do
- begin
- ioNamePtr := @FName;
- ioVrefNum := vrefnum;
- end; {with}
-
- {allocate storate for the list}
- htext := NewHandle(0);
- returnstr := chr(13); {----•••• do you need this? Yes, you bimbo!!}
- colonstr := ':';
-
- {search the specified directory}
- EnumerateCatalog(dirid);
-
- {return the information}
- MCListDirectory := htext;
- end; {MCSearchCatalog}
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• Directory searching function ••}
-
- {This procedure searches a specified directory, and returns either a list of folders, }
- {files or both.}
- {if folders are wanted, you can also specify a minimum number of items to be in the folder}
-
- function MCSearchCatalog (MinimumItems: integer;
- vrefnumtosearch: integer;
- DirIDToSearch: Longint;
- findfolders: boolean;
- findfiles: boolean;
- ignorenoaccessfolders: boolean): Handle;
- var
- FName: Str255;
- myCPB: CInfoPBRec;
- err: OSErr;
- TotalFiles, TotalDirectories: integer;
- htext: Handle;
- strlen: integer;
- returnstr: str255;
-
- procedure EnumerateCatalog (minitems: integer;
- dirIDToSearch: longint);
- {performs the same function as PBCatSearch - From TN #68, I think...}
- var
- index: integer;
- access: str255;{ignore}
-
- begin {EnumerateCatalog}
- index := 1;
- repeat
- MCNextAnimCursor;
- {set up the search}
- FName := '';
- myCPB.ioFDirIndex := index;
- myCPB.ioDrDirID := dirIDToSearch;
-
- err := PBGetCatInfo(@myCPB, FALSE); {actually get the information}
-
- if err = noErr then
- if BitTst(@myCPB.ioFlAttrib, 3) then
- begin {we have a directory}
- TotalDirectories := TotalDirectories + 1;
- if findfolders then
- if myCPB.ioDrNmFls >= minitems then
- if ignorenoaccessfolders then
- {make sure we aren't collecting folders which the user can't access}
- begin
- if MCUserCanAccessDir(FName, myCPB.ioVrefnum, myCPB.ioDirID, access, err) then
- begin
- strlen := length(myCPB.ioNamePtr^);
- hlock(htext);
- {append the string}
- err := ptrAndHand(ptr(ord4(@myCPB.ioNamePtr^) + 1), htext, strlen);
- {append a return after the string}
- err := ptrAndHand(ptr(ord4(@returnstr) + 1), htext, 1);
- hunlock(htext)
- end;
- end
- else {if list every folder}
- begin {output the name of the folder in some manner}
- strlen := length(myCPB.ioNamePtr^);
- hlock(htext);
- {append the string}
- err := ptrAndHand(ptr(ord4(@myCPB.ioNamePtr^) + 1), htext, strlen);
- {append a return after the string}
- err := ptrAndHand(ptr(ord4(@returnstr) + 1), htext, 1);
- hunlock(htext)
- {writeln(myCPB.ioNamePtr^) {if greater than minitems}
- end
- else
- {do nothing if has 0 items}
- ;
- {EnumerateCatalog(myCPB.ioDrDirID); {only call this if we want a recursive search}
- err := 0; {clear error return on way back}
- end {if BitTst}
- else
- begin {we have a file}
- TotalFiles := TotalFiles + 1;
- if findfiles then
- begin
- strlen := length(myCPB.ioNamePtr^);
- hlock(htext);
- err := ptrAndHand(ptr(ord4(@myCPB.ioNamePtr^) + 1), htext, strlen);
- err := ptrAndHand(ptr(ord4(@returnstr) + 1), htext, 1);
- hunlock(htext)
- end;
- end; {else}
- index := index + 1;
- until (err <> noErr);
- end; {EnumerateCatalog}
-
-
- begin {EnumerShell}
- TotalFiles := 0;
- TotalDirectories := 0;
-
- with MyCPB do
- begin
- ioNamePtr := @FName;
- ioVrefNum := vrefnumtosearch;
- end; {with}
-
- {allocate storate for the list}
- htext := NewHandle(0);
- returnstr := chr(13);
-
- {search the specified directory}
- EnumerateCatalog(MinimumItems, DirIDToSearch);
-
- {return the information}
- MCSearchCatalog := htext;
- end; {MCSearchCatalog}
-
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• finds the system folder in system 6 or 7. Untested. ••}
- function MCFindSystemFolder (var foundVRefNum: integer;
- var foundDirID: longint): OSErr;
- {Taken from code found in Q&A Stack}
- var
- gesResponse: longint;
- envRec: SysEnvRec;
- myWDPB: WDPBRec;
- volName: str32;
- err: OSerr;
-
- begin
- MCFindSystemFolder := noErr;
-
- foundVRefNum := 0;
-
- foundDirID := 0;
- if GestaltAvailable then
- begin
- if (Gestalt(gestaltFindFolderAttr, gesResponse) = noErr) and (BitTst(@gesResponse, 31 - gestaltFindFolderPresent) = TRUE) then
- MCFindSystemFolder := FindFolder(kOnSystemDisk, kSystemFolderType, kDontCreateFolder, foundVRefNum, foundDirID);
- end
- else if (SysEnvirons(curSysEnvVers, envRec) = noErr) then
- begin
- myWDPB.ioVRefNum := envRec.sysVRefNum;
- volName := ''; {/* Zero volume name */}
- myWDPB.ioNamePtr := @volName;
- myWDPB.ioWDIndex := 0;
- myWDPB.ioWDProcID := 0;
- err := PBGetWDInfo(@myWDPB, false);
- if (err = noErr) then
- begin
- foundVRefNum := myWDPB.ioWDVRefNum;
- foundDirID := myWDPB.ioWDDirID;
- end
- else
- MCFindSystemFolder := err;
- end;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns a vrefnum for a specified volume name ••}
- function MCGetVrefNum;
- var
- myFSSpec: FSSpec;
- myErr: OSErr;
- tmpvol: str255;
- pbc: HParmBlkPtr;
- begin
- {System 6 & 7 compatible}
- if volname[length(volname)] <> ':' then
- tmpvol := concat(volname, ':')
- else
- tmpvol := volname;
- pbc := HParmBlkPtr(NewPtr(sizeof(HParamBlockRec)));
- with pbc^ do
- begin
- ioCompletion := nil;
- ioNamePtr := @tmpvol;
- ioVRefNum := 0;
- ioFDirIndex := 0;
- ioVolIndex := -1;
- end;
- myErr := PBHGetVInfo(pbc, FALSE);
- if myErr = noErr then
- begin
- vrefnum := pbc^.ioVrefNum;
- end;
- MCGetVrefNum := myErr;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns true if error was caused because file was busy. ••}
- function MCIsBusyError (err: OSErr): boolean;
- begin
- case err of
- fBsyErr, opWrErr, afpFileBusy:
- MCIsBusyError := true;
- otherwise
- MCIsBusyError := false;
- end;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns true if file is open elsewhere ••}
-
- function MCFSSpecIsBusy (myfs: FSSpec): boolean; {must only be a file}
- {DOESN"T REALLY WORK...bit may be wrong...}
- {Don't really need it anyway, checkout MCGetFSSpecFileNoClose}
- var
- myCPB: CInfoPBRec;
- err: OSErr;
- begin
- MCFSSpecIsBusy := false;
- with MyCPB do
- begin
- ioNamePtr := @myfs.name;
- ioVrefNum := myfs.vrefnum;
- ioDirID := myfs.parid;
- ioFDirIndex := 0;
- ioFlParID := myfs.parid;
- end; {with}
-
- {must test bit 7, whatever that translates to... I think it is 7-x, so here we use 0}
- err := PBGetCatInfo(@myCPB, FALSE); {actually get the information}
- if err = noErr then
- if BitTst(@myCPB.ioFlAttrib, 1) then
- MCFSSpecIsBusy := true
- else
- MCFSSpecIsBusy := false;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns true if fsspec designates a folder ••}
-
- function MCFSSpecIsFolder (myfs: FSSpec): boolean;
- var
- myCPB: CInfoPBRec;
- err: OSErr;
- begin
- MCFSSpecIsFolder := false;
- with MyCPB do
- begin
- ioNamePtr := @myfs.name;
- ioVrefNum := myfs.vrefnum;
- ioDirID := 0;
- ioDrDirID := 0;
- ioFDirIndex := 0;
- ioDrParID := myfs.parid;
- ioFlParID := myfs.parid;
- end; {with}
-
- err := PBGetCatInfo(@myCPB, FALSE); {actually get the information}
- if err = noErr then
- if BitTst(@myCPB.ioFlAttrib, 3) then
- MCFSSpecIsFolder := true
- else
- MCFSSpecIsFolder := false;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns name of volume designated with vrefnum ••}
-
- function MCGetVolName (vrefnum: integer;
- var volname: str255): OSErr;
- var
- pb: ParamBlockRec;
- begin
- volname := '';
- with pb do
- begin
- ioCompletion := nil;
- ioNamePtr := @volname;
- ioVrefNum := vrefnum;
- iovolIndex := 0;
- end;
- MCGetVolName := PBGetVInfo(@pb, false);
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns file/folder at end of path - if path ends with a ":", returns that ••}
- function MCGetLeafOfPath (path: str255): str255;
- var
- offset: integer;
- isfolder: boolean;
- begin
- if path[length(path)] = ':' then
- begin
- path[length(path)] := '@';
- isfolder := true;
- end
- else
- isfolder := false;
- offset := pos(':', path);
- repeat
- delete(path, 1, offset);
- offset := pos(':', path);
- until offset = 0;
- if isfolder then
- if path[length(path)] = '@' then
- path[length(path)] := ':'; {convert back to folder}
- MCGetLeafOfPath := path;
- end;
-
- {•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
- {•• returns access privileges for a folder in the form: uu••}
- function MCUserCanAccessDir (volname: Str255;
- vrefnum: integer;
- dirID: longint;
- var myAccess: str255;
- var myErr: OSErr): boolean;
-
- var
- pb: HParamBlockRec;
- accessprivs: longint;
- begin
- if (dirid <> 0) then {in case passed in a full path name}
- volname := MCPathNameFromDirID(dirid, vrefnum);
- with pb do
- begin
- ioCompletion := nil;
- ioNamePtr := @volname;
- ioVrefNum := vrefnum;
- ioDirID := dirid;
- end;
- myErr := PBHGetDirAccess(@pb, false);
- {at the moment, we only care if the user has access to it or not.}
- if myErr = noErr then
- begin
- accessprivs := pb.ioACAccess;
- if accessprivs < 0 then
- accessprivs := (accessprivs - ($80000000)) div 16777216
- else
- accessprivs := accessprivs div 16777216;{get the high two bytes}
- case accessprivs of
- 0:
- begin
- MCUserCanAccessDir := false;
- myAccess := '---';
- end;
- 1:
- begin
- myAccess := '--s';
- MCUserCanAccessDir := false;
- end;
- 2:
- begin
- myAccess := '-r-';
- MCUserCanAccessDir := false;
- end;
- 3:
- begin
- myAccess := '-rs'; {minimum required to be able to read files in a dir, I think}
- MCUserCanAccessDir := true;
- end;
- 4, 5, 6:
- begin
- myAccess := '-rs';
- MCUserCanAccessDir := true;
- end;
- 7:
- begin
- myAccess := 'wrs';
- MCUserCanAccessDir := true;
- end;
- otherwise
- begin
- MCUserCanAccessDir := false;
- myAccess := '---';
- end;
- end;
- end
- else
- begin
- MCUserCanAccessDir := false;
- end;
- end;
-
-
- function MCGetDirIDofDir (myFS: FSSpec;
- isvolume: Boolean;
- var dirid: longint): OSErr;
- var
- myCPB: CInfoPBRec;
- err: OSErr;
- tmps: Str255;
- begin
- MCGetDirIDofDir := noErr;
- if isvolume then
- tmps := concat(myfs.name, ':')
- else
- tmps := myfs.name;
- with MyCPB do
- begin
- ioNamePtr := @tmps;
- ioVrefNum := myfs.vrefnum;
- ioDirID := 0;
- if isvolume then
- ioDrDirID := 0
- else
- ioDrDirID := myfs.parid;
- ioFDirIndex := 0;
- ioDrParID := myfs.parid;
- end; {with}
-
- err := PBGetCatInfo(@myCPB, FALSE);
- if err = noErr then
- dirid := mycpb.ioDirID
- else
- MCGetDirIDofDir := err;
- end;
-
- end.